package weather.language.forecast;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;


import weather.connector.WeatherInfoProvider;
import weather.connector.exceptions.DateNotSupportedException;
import weather.dictionary.*;
import weather.language.Site;
import weather.language.WhereAndWhen;
import weather.util.Dates;

/**
 * Prepare answer map for a given question
 * @author Marian Szczykulski
 *
 */
public class WeatherInformator 
{
	/**
	 * Asks for a weather
	 * @param question - question about a weather
	 * @return	answer map for a given question
	 */
	public static TreeMap<Date, HashMap<Site, WeatherAnswer>> ask(WeatherQuestion question)
	{
		TreeMap<Date, HashMap<Site, WeatherAnswer>> result = new TreeMap<Date, HashMap<Site, WeatherAnswer>>();
		//HashMap<Site, WeatherAnswer> siteToAnswer = new HashMap<Site, WeatherAnswer>();
		
		WeatherInfoProvider wip = WeatherInfoProvider.instance();
		WhereAndWhen scale[] = question.getWhereAndWhen();
		
		for (WhereAndWhen whereAndWhen : scale) 
		{
			String query = SiteToQueryMappingDictionary.instance().getValue(whereAndWhen.getWhere());
			WeatherAnswer answer = new WeatherAnswer();
			int date = Dates.numberOfDaysBetween(new Date(), whereAndWhen.getWhen());
			try
			{
				if(question.getQuestionAboutConditions()!=null)
				{//question about conditions
					String cond = wip.getWeatherCondition(query, date);
					answer.setGroup(question.getQuestionAboutConditions());
					answer.setCondition(new Condition(cond));
			
				}
				if(question.isQuestionAboutHighTemperature())
				{
					String temp = wip.getHighTemperatureAsString(query, date);
					answer.setHighTemperature(temp);
				
				}
				if(question.isQuestionAboutLowTemperature())
				{
					String temp = wip.getLowTemperatureAsString(query, date);
					answer.setLowTemperature(temp);
				}
				if(question.isQuestionAboutAverageTemperature())
				{
					String h = wip.getHighTemperatureAsString(query, date);
					String l = wip.getLowTemperatureAsString(query, date);
					int avg = (Integer.parseInt(l)+Integer.parseInt(h))/2;
					answer.setAvgTemperature(Integer.toString(avg));
				}
			}
			catch (DateNotSupportedException e) 
			{
				answer = null;
			}
			
			HashMap<Site, WeatherAnswer> siteToAnswer = result.get(whereAndWhen.getWhen());
			if(siteToAnswer == null)
			{
				siteToAnswer = new HashMap<Site, WeatherAnswer>();
				result.put(whereAndWhen.getWhen(), siteToAnswer);
				
			}
				
			siteToAnswer.put(whereAndWhen.getWhere(), answer);
		}
		return result;
	}
	

	public static String generateAnswer(TreeMap<Date, HashMap<Site, WeatherAnswer>> info)
	{
		String answer = "";
		//SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
		 
		Set<Date> keys = info.keySet();
		Iterator<Date> iter = keys.iterator();
		boolean isInCorrect = false;
		
		while(iter.hasNext())
		{
			Date d = iter.next();
			HashMap<Site, WeatherAnswer> places = info.get(d);
			if(isInCorrect)
				answer+=", but ";
			answer += d.toString();//sdf.format(d);
			
			Set<Entry<Site,WeatherAnswer>> entries= places.entrySet();
			Iterator<Entry<Site,WeatherAnswer>> iter2 = entries.iterator();
			String placePrefix = " in ";
			while(iter2.hasNext())
			{
				Entry<Site, WeatherAnswer> entr = iter2.next();
				WeatherAnswer wa = entr.getValue();
				if(wa == null)
				{
					answer = "I do not know nothing about weather in "+entr.getKey().getMainName()+ " "+d.toString();
					isInCorrect = true;
					continue;
				}
				isInCorrect = false;
				answer+= placePrefix+entr.getKey().getMainName();
				String separator = " ";
				if(wa.isAnswerCorrect()&&wa.toStringCondition()!=null)
				{
					answer+=" " + wa.toStringCondition();
					separator = ", ";
				}
				else if(wa.toStringCondition()!=null)
				{
					answer+=" information about "+wa.groupsToString() + " is not exactly known, but I know that "+wa.toStringCondition();
					separator = ", ";
				}
				
				if(wa.toStringHighTemperature()!=null)	
				{
					answer+=separator + wa.toStringHighTemperature();
					separator = ", ";
				}
				if(wa.toStringLowTemperature()!=null)
				{
					answer+=separator + wa.toStringLowTemperature();
					separator = " and ";
				}
				if(wa.toStringMidTemperature()!=null)
					answer+=separator + wa.toStringMidTemperature();
				answer+=".";
				placePrefix = "In ";
			}
			if(!isInCorrect)
				answer+="\n";
			
		}
		String firstL = answer.substring(0, 1);
		if(firstL.matches("[a-z]"))
		{
			answer = answer.replaceFirst("[a-z]",firstL.toUpperCase());
		}
		boolean nextToSet = false;
		int i = 0;
		char[] answerArray =  answer.toCharArray();
		for(char ch: answerArray)
		{	
			if(nextToSet)
			{
				if(Character.isLetter(ch))
				{
					answerArray[i] = Character.toUpperCase(answerArray[i]);
					nextToSet = false;
				}
			}
			if(ch=='.')
				nextToSet=true;
			i++;
		}
		answer = new String(answerArray);
		return answer;
	}
	
	public static String askForWeather(WeatherQuestion question)
	{
		return generateAnswer(ask(question));
	}
	
	public static final void main(String[] args)
	{
		WeatherQuestion question1 = new WeatherQuestion();
		Site s1 = new Site("Warszawa");
		Site s2 = new Site("Torun");
		Site s3 = new Site("Wroclaw");
		Date d1 = new Date((new Date()).getTime()+10000+Dates.DAY_LENGTH_IN_MILLISECONDS);//tommorow
		Date d2 = new Date((new Date()).getTime()+10000+2*Dates.DAY_LENGTH_IN_MILLISECONDS);//tommorow
		Date d3 = new Date((new Date()).getTime()+10000+3*Dates.DAY_LENGTH_IN_MILLISECONDS);//tommorow
		question1.addWhereAndWhen(new WhereAndWhen(s1, d1));
		question1.addWhereAndWhen(new WhereAndWhen(s1, d2));
		question1.addWhereAndWhen(new WhereAndWhen(s1, d3));
		
		question1.addWhereAndWhen(new WhereAndWhen(s2, d1));
		question1.addWhereAndWhen(new WhereAndWhen(s2, d2));
		question1.addWhereAndWhen(new WhereAndWhen(s2, d3));
		
		question1.addWhereAndWhen(new WhereAndWhen(s3, d1));
		question1.addWhereAndWhen(new WhereAndWhen(s3, d2));
		question1.addWhereAndWhen(new WhereAndWhen(s3, d3));
		
		ConditionsGroup cg = new ConditionsGroup("RAIN");
		cg.addCondition(new Condition("RAIN"));
		cg.addCondition(new Condition("CHANCE_OF_RAIN"));
		question1.addQuestionAboutConditions(cg);
		
		System.out.println(askForWeather(question1));
	}
}
